package com.lh.center.common.web.config;

import cn.hutool.core.util.ClassUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.lh.center.common.base.session.SessionUser;
import com.lh.center.common.enums.LogLevel;
import com.lh.center.common.util.LoggerUtil;
import com.lh.center.common.util.SpringUtils;
import com.lh.center.common.web.CommonWebAutoConfiguration;
import com.lh.center.common.web.session.SessionLogStorage;
import com.lh.center.common.web.session.SessionOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.logging.Log;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.util.ArrayList;
import java.util.List;

/**
 * mybatis的日志打印实现
 */
public class MybatisLogImpl implements Log {

    private CommonWebAutoConfiguration configuration;
    private final String clazz;

    public MybatisLogImpl(String clazz) {
        this.clazz = clazz;
    }

    @Override
    public boolean isDebugEnabled() {
        return true;
    }

    @Override
    public boolean isTraceEnabled() {
        return true;
    }

    @Override
    public void error(String s, Throwable e) {
        LoggerUtil.error(parseClass(),e,s);
    }

    @Override
    public void error(String s) {
        LoggerUtil.error(parseClass(),s);
    }

    @Override
    public void debug(String s) {
        if(checkPrint(LogLevel.INFO,s)){
            LoggerUtil.info(parseClass(),s);
        }
    }

    @Override
    public void trace(String s) {
        //查询语句的具体返回条目会通过trace进行打印
        if(checkPrint(LogLevel.TRACE,s)){
            LoggerUtil.debug(parseClass(),s);
        }
    }

    @Override
    public void warn(String s) {
        if(checkPrint(LogLevel.WARN,s)){
            LoggerUtil.warn(parseClass(),s);
        }
    }

    private Class<?> parseClass(){
        String clazz = this.clazz.substring(0, this.clazz.lastIndexOf("."));
        try {
            return ClassUtil.loadClass(clazz);
        }catch (Exception e) {
            return this.getClass();
        }
    }

    private boolean checkPrint(LogLevel level,String msg,Object...args){
        if(configuration == null){
            this.configuration = SpringUtils.getBean(CommonWebAutoConfiguration.class);
        }
        if(configuration == null){
            return false;
        }
        if(SessionOperation.user.get()==null && SessionOperation.dubboConsumerUser.get()==null){
            return false;
        }
        if(StringUtils.isNotBlank(configuration.getLogByAssignAccount())){
            String logByAssignAccount = configuration.getLogByAssignAccount();
            //获取当前用户账号进行对比
            SessionUser user = SessionOperation.getUserNotException();
            String currentSessionUserAccount = "";
            String dubboSessionUserAccount = "";
            if(user != null){
                currentSessionUserAccount = user.getAccount();
            }
            if(SessionOperation.dubboConsumerUser.get() != null){
                dubboSessionUserAccount = SessionOperation.dubboConsumerUser.get().getAccount();
            }
            return currentSessionUserAccount.equals(logByAssignAccount) || dubboSessionUserAccount.equals(logByAssignAccount);
        }
        PathMatcher matcher = new AntPathMatcher();
        boolean match = configuration.getLogUri().stream().anyMatch(uri -> matcher.match(uri, this.clazz));
        if(!match){
            SessionUser user = SessionOperation.getUserNotException();
            if(user == null){
                return false;
            }
            List<SessionLogStorage> logs = SessionOperation.logs.get();
            if(CollectionUtils.isEmpty(logs)){
                SessionOperation.logs.set(new ArrayList<>());
            }
            SessionLogStorage storage = new SessionLogStorage();
            storage.setArgs(args);
            storage.setLevel(level);
            storage.setMsg(msg);
            storage.setClazz(parseClass());
            SessionOperation.logs.get().add(storage);
        }

        return match;
    }
}
